package com.card.hwatt.controllers;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.card.hwatt.assembler.*;
import com.card.hwatt.dto.*;
import com.card.hwatt.service.*;

/**
 * 月考勤
 * @author Administrator
 *
 */
@Controller
@Scope("prototype")
@RequestMapping("/monthwork")
public class MonthWorkController extends BaseController {

	@Autowired
	@Qualifier("employeeService")
	private EmployeeService employeeService;

	@Autowired
	@Qualifier("cardService")
	private CardService cardService;

	@Autowired
	@Qualifier("scheduleService")
	private ScheduleService scheduleService;

	@Autowired
	@Qualifier("holidayService")
	private HolidayService holidayService;

	@Autowired
	@Qualifier("leaveService")
	private LeaveService leaveService;

	@Autowired
	@Qualifier("departmentService")
	private DepartmentService departmentService;

	@RequestMapping("/index")
	public String index() {
		return "monthwork";
	}

	@RequestMapping(value = "/print")
	public void print(HttpServletRequest request, HttpServletResponse response,
			Long id, String key, Integer year, Integer month) {

		if (id == null) {
			return;
		}

		Department department = DepartmentAssembler.convert(departmentService
				.get(id));
		if (department == null) {
			return;
		}

		List<Employee> employees = loadEmployee(id, key);
		List<Card> cards = loadCard(id, key, year, month);
		List<Leave> leaves = loadLeave(id, key, year, month);
		List<Holiday> holidaies = loadHoliday(year, month);
		Schedule schedule = ScheduleAssembler.convert(scheduleService.get(
				String.format("%d-%d-01", year, month), id));

		Calendar end = Calendar.getInstance();
		end.set(year, month - 1, 1, 0, 0, 0);
		end.add(Calendar.MONTH, 1);
		List<CardRecord> list = CardRecordAssembler.convert(employees, cards,
				schedule, DateFormatUtils.format(end, "yyyy-MM-dd"));

		Map<String, Object> result = MonthWorkAssembler.convert(employees,
				list, leaves, holidaies, schedule);

		@SuppressWarnings("unchecked")
		List<MonthWork> rows = (List<MonthWork>) result.get("rows");

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("year", year);
		params.put("month", month);
		params.put("title", department.name
				+ year
				+ "年"
				+ month
				+ "月"
				+ (StringUtils.isEmpty(key) ? StringUtils.EMPTY : "(" + key
						+ ")") + "员工考勤 统 计 表");
		HttpSession session = request.getSession();
		Object user = session.getAttribute("user");
		params.put("name", user == null ? StringUtils.EMPTY : "打印人：" + user);
		params.put("date",
				"打印日期：" + DateFormatUtils.format(new Date(), "yyyy-MM-dd"));

		MonthWork[] footers = ((MonthWork[]) result.get("footer"));
		MonthWork footer = footers[footers.length - 1];
		Class<?> cls = footer.getClass();
		for (int i = 1; i <= 31; i++) {
			try {
				String fieldName = "d" + i;
				Field field = cls.getField(fieldName);
				params.put(fieldName, field.get(footer).toString());
			} catch (Exception e) {
			}
		}

		this.print(request, response, "monthwork", rows, params);
	}

	private List<Employee> loadEmployee(Long id, String key) {
		List<Object> params = new ArrayList<Object>();

		params.add("%@" + id + "@%");

		if (StringUtils.isNotEmpty(key)) {
			params.add("%" + key + "%");
			params.add("%" + key + "%");
		}
		List<Employee> result = EmployeeAssembler
				.convert(employeeService.loadAll(new PageParam(
						0,
						0,
						" department.path like ? "
								+ (StringUtils.isNotEmpty(key) ? " and ( name like ? or employeeCode like ? ) "
										: StringUtils.EMPTY), params,
						" employeeCode asc ")).rows);

		return result;
	}

	private List<Card> loadCard(Long id, String key, Integer year, Integer month) {

		if (year == null || month == null) {
			return new ArrayList<Card>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd HH:mm:ss" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(
					String.format("%d-%d-01 00:00:00", year.intValue(),
							month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DATE, 1);
		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();
		params.add("%@" + id + "@%");
		params.add(new java.sql.Date(startDate.getTime()));
		params.add(new java.sql.Date(endDate.getTime()));

		if (StringUtils.isNotEmpty(key)) {
			params.add("%" + key + "%");
			params.add("%" + key + "%");
		}

		List<Card> result = CardAssembler
				.convert(cardService
						.loadAll(new PageParam(
								0,
								0,
								" employee.department.path like ? and date >= ? and date < ? "
										+ (StringUtils.isNotEmpty(key) ? " and ( employee.name like ? or employee.employeeCode like ? ) "
												: StringUtils.EMPTY), params,
								" date asc ")).rows);

		return result;
	}

	private List<Leave> loadLeave(Long id, String key, Integer year,
			Integer month) {
		if (year == null || month == null) {
			return new ArrayList<Leave>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(String.format("%d-%d-01",
					year.intValue(), month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);

		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();

		String pattern = "yyyyMMdd";
		params.add(DateFormatUtils.format(startDate, pattern));
		params.add(DateFormatUtils.format(endDate, pattern));

		params.add("%@" + id + "@%");

		if (StringUtils.isNotEmpty(key)) {
			params.add("%" + key + "%");
			params.add("%" + key + "%");
		}

		List<Leave> result = LeaveAssembler
				.convert(leaveService
						.loadAll(new PageParam(
								0,
								0,
								" name >= ? and name < ? and employee.department.path like ? "
										+ (StringUtils.isNotEmpty(key) ? " and ( employee.name like ? or employee.employeeCode like ? ) "
												: StringUtils.EMPTY), params,
								" name desc ")).rows);
		return result;
	}

	private List<Holiday> loadHoliday(Integer year, Integer month) {
		if (year == null || month == null) {
			return new ArrayList<Holiday>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(String.format("%d-%d-01",
					year.intValue(), month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);

		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();

		String pattern = "yyyyMMdd";
		params.add(DateFormatUtils.format(startDate, pattern));
		params.add(DateFormatUtils.format(endDate, pattern));

		List<Holiday> result = HolidayAssembler.convert(holidayService
				.loadAll(new PageParam(0, 0, " id >= ? and id < ? ", params,
						" id desc ")).rows);
		return result;
	}

	@RequestMapping("/loadAll")
	public @ResponseBody
	Map<String, Object> loadAll(Long id, String key, Integer year, Integer month) {
		if (id == null || id == 2) {
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("total", 0);
			m.put("rows", new Object[0]);
			m.put("footer", new Object[0]);
			return m;
		}

		List<Employee> employees = loadEmployee(id, key);
		List<Card> cards = loadCard(id, key, year, month);
		List<Leave> leaves = loadLeave(id, key, year, month);
		List<Holiday> holidaies = loadHoliday(year, month);
		Schedule schedule = ScheduleAssembler.convert(scheduleService.get(
				String.format("%d-%d-01", year, month), id));

		Calendar end = Calendar.getInstance();
		end.set(year, month - 1, 1, 0, 0, 0);
		end.add(Calendar.MONTH, 1);

		List<CardRecord> list = CardRecordAssembler.convert(employees, cards,
				schedule, DateFormatUtils.format(end, "yyyy-MM-dd"));

		Map<String, Object> result = MonthWorkAssembler.convert(employees,
				list, leaves, holidaies, schedule);
		return result;
	}
}
